﻿using System;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;

public abstract class ServerSocket
{
    public abstract ISocketServer socketServerListenr { get; }

    public IEncode encoder { get; set; }
    public IDecode decoder { get; set; }

    public const byte PingByte = 1;

    protected byte[] m_Buffer = new byte[2048];//[8192 * 2];// new byte[8192 * 2];// 当前使用的缓冲区, appstore receipt 长度加上接口的参数 会超过8192

    public abstract bool connected { get; }

    protected Socket m_Socket;

    public Socket socket { get { return m_Socket; } }
  
    public virtual void Start(int port, int maxConnectCount)
    {

    }
    
    public virtual void BeginReceive()
    {

    }
    protected Packet m_Packet;
    protected object _packetBaton = new object();
    //List<Packet> m_Packets = new List<Packet>();

    protected virtual List<byte[]> TryGetMessageWithReceiveData(byte[] newData)
    {
        List<byte[]> res = new List<byte[]>();
        int receiveCount = newData.Length;
        byte[] remain = newData;

        lock (_packetBaton)
        {
            Packet packet = m_Packet;

            if (!Packet.CheckHeadData(remain))
            {
                if (packet == null)
                {
                    GameDebug.LogError($"处理数据出错  m_Packet == null");
                    this.Disconnect();
                    return null;
                }
                remain = packet.AddData(remain);

                if (packet.receiveEnd)
                {
                    byte[] data = packet.data;

                    if (decoder != null)
                    {
                        //GameDebug.Log($"密文是：{BitConverter.ToString(data)}");
                        data = decoder.Decrypt(data);
                        //GameDebug.Log($"明文是：{BitConverter.ToString(data)}");
                    }
                    res.Add(data);
                }
            }

            while (remain != null)
            {
                Packet newPacket = new Packet();

                remain = newPacket.OnReceiveHead(remain);
                if (newPacket.receiveEnd)
                {
                    //GameDebug.Log($"新包处理数据：{newPacket.contentLength}");

                    byte[] data = newPacket.data;

                    if (decoder != null)
                    {
                        //GameDebug.Log($"密文是：{BitConverter.ToString(data)}");
                        data = decoder.Decrypt(data);
                        //GameDebug.Log($"明文是：{BitConverter.ToString(data)}");
                    }
                    res.Add(data);
                }
                else
                {
                    //GameDebug.Log($"新包：{newPacket.contentLength}");
             
                    m_Packet = newPacket;
                    //m_Packets.Add(newPacket);
                }
            }
        }
        return res;
    }

    public virtual void Release()
    {
      
    }

    protected virtual void Disconnect()
    {

    }
    /// <summary>
    /// 发送数据
    /// </summary>
    /// <param name="client"></param>
    /// <param name="packet"></param>
    public virtual void SendPacket(byte[] packet,EndPoint endPoint)
    {
        if (encoder != null)
        {
            packet = encoder.Encrypt(packet);
        }

        byte[] headBytes = System.Text.Encoding.UTF8.GetBytes(Packet.Head);

        int length = packet.Length;
        byte[] lenBytes = BitConverter.GetBytes(length);

        int packetHeadCount = headBytes.Length + lenBytes.Length;

        byte[] data = new byte[packetHeadCount + length];

        System.Array.Copy(headBytes, 0, data, 0, headBytes.Length);
        System.Array.Copy(lenBytes, 0, data, headBytes.Length, lenBytes.Length);
        System.Array.Copy(packet, 0, data, headBytes.Length + lenBytes.Length, packet.Length);

        //GameDebug.Log($"发送长度  packetHeadCount:{packetHeadCount}   dataLength:{data.Length}  endPoint:{endPoint}");

        _SendData(data, endPoint);

        Thread.Sleep(15);
    }
    
    public abstract void _SendData( byte[] data, EndPoint endPoint);
    

    public void LogSocketException(Exception e)
    {
        if(e == null)
        {
            GameDebug.LogError("LogSocketException e == null");
        }
        else
        {
            GameDebug.LogError(e.Message + "\n" +e.StackTrace);
        }
    }

    public static void TryParseHost(string host, out IPAddress ipAddress)
    {
        ipAddress = null;

        bool isIP = IPAddress.TryParse(host, out ipAddress);
        if (isIP)
        {
            return ;
        }

        IPAddress[] ipAddressArray = Dns.GetHostAddresses(host);

        GameDebug.Log($"TryParseHost->ipAddressArray:{ipAddressArray.GetArrStr()}");

        ipAddress = ipAddressArray[0];
    }
}

